/**
 * David Qiu <david@davidqiu.com>
 * School of Software, Sun Yat-Sen University.
 */


#include <iostream>
#include <stack>
#include <vector>
#include <algorithm>
#include <cstdlib>
using namespace std;

//#define DEBUG
#define SIZE ((8))


/**
 * The point on the chessboard.
 */
struct Point
{
  int x, y;
};


/**
 * The search boundary of the stack.
 */
const int searchBoundary = SIZE * SIZE - 1;


/**
 * The search stack.
 */
stack< vector<Point> > s;


/**
 * The chessboard of two dimensions, which indicates if the points 
 * on it has been gone through or not. It will be initialized and 
 * released within the main function.
 * 
 * *--------------> x
 * | 1 2 3 4 5 6 ..
 * | 9 ..
 * |
 * |
 * |
 * y
 */
bool** chessboard = NULL;


/**
 * Check if a point is available to be occupy.
 *
 * param p the point to check.
 * return a bool indicating if the point is available.
 */ 
bool isValid(Point p)
{
  return !(p.x<0||p.y<0||p.x>=SIZE||p.y>=SIZE||chessboard[p.y][p.x]);
}


/**
 * The successor collection of a specific point. Note that this 
 * function is related to the chessboard.
 *
 * @param cp the point of the current position of the horse.
 * @return the collection of the valid point successors.
 */
vector<Point> successors(Point cp)
{
  vector<Point> result;
  Point p;
  
  // Check the expected successors
  // +1 -2
  p.x = cp.x + 1; p.y = cp.y - 2;
  if(isValid(p)) result.push_back(p);
  // +2 -1
  p.x = cp.x + 2; p.y = cp.y - 1;
  if(isValid(p)) result.push_back(p);
  // +2 +1
  p.x = cp.x + 2; p.y = cp.y + 1;
  if(isValid(p)) result.push_back(p);
  // +1 +2
  p.x = cp.x + 1; p.y = cp.y + 2;
  if(isValid(p)) result.push_back(p);
  // -1 +2
  p.x = cp.x - 1; p.y = cp.y + 2;
  if(isValid(p)) result.push_back(p);
  // -2 +1
  p.x = cp.x - 2; p.y = cp.y + 1;
  if(isValid(p)) result.push_back(p);
  // -2 -1
  p.x = cp.x - 2; p.y = cp.y - 1;
  if(isValid(p)) result.push_back(p);
  // -1 -2
  p.x = cp.x - 1; p.y = cp.y - 2;
  if(isValid(p)) result.push_back(p);
  
  // Return the result
  return result;
}


/**
 * Compare the successor numbers of two points in greater order.
 *
 * param pa the first point to compare.
 * param pb the second point to compare.
 * return a bool indicating the greater order relationship of the two points.
 */
bool compare(Point pa, Point pb)
{
  return (successors(pa).size() > successors(pb).size());
}


/**
 * Search the top of the current search stack. It is a recursive function.
 *
 * @return a bool indicating if the goal state is found.
 */
bool search()
{
  #ifdef DEBUG
  static int searchLevel = 0;
  ++searchLevel;
  cout << "Search Level: " << searchLevel << endl;
  #endif
  // Go through the current point
  #ifdef DEBUG
  cout << "Gone through: (" << s.top()[s.top().size()-1].x << ", " << s.top()[s.top().size()-1].y << ")" << endl;
  #endif
  chessboard[s.top()[s.top().size()-1].y][s.top()[s.top().size()-1].x] = true; 
  vector<Point> cur = successors(s.top()[s.top().size()-1]);
  #ifdef DEBUG
  cout << "Sucessors: ";
  for(int i=0;i<cur.size();++i) cout << "(" << cur[i].x << ", " << cur[i].y << ") ";
  cout << endl;
  system("pause");
  #endif
  
  // Check goal state
  if(cur.size()==0)
  {
    // Goal state found
    if(s.size()==searchBoundary)
    {
      #ifdef DEBUG
      cout << "Goal!!!" << endl;
      system("pause");
      #endif
      return true;
    }
    
    // Fail the current point
    // Erase the current step
    #ifdef DEBUG
    cout << "Fail the level .." << endl;
    cout << "Erase: (" << s.top()[s.top().size()-1].x << ", " << s.top()[s.top().size()-1].y << ")" << endl;
    system("pause");
    --searchLevel;
    cout << "Go back.. " << endl;
    cout << "Search Level: " << searchLevel << endl;
    #endif
    chessboard[s.top()[s.top().size()-1].y][s.top()[s.top().size()-1].x] = false;
    return false;
  }
  
  // Sort the points
  sort(cur.begin(), cur.end(), compare);
  
  // Search the next points
  s.push(cur);
  while(s.top().size()>0)
  {
    #ifdef DEBUG
    cout << "Search List: ";
    for(int i=0;i<s.top().size();++i) cout << "(" << s.top()[i].x << ", " << s.top()[i].y << ") ";
    cout << endl;
    system("pause");
    #endif
    // Check if find the goal state
    if(search()) return true;
    
    // Search the next state
    s.top().pop_back();
  }
  
  // Fail the next layer
  // Erase the current step
  s.pop();
  #ifdef DEBUG
  cout << "Fail the level .." << endl;
  cout << "Erase: (" << s.top()[s.top().size()-1].x << ", " << s.top()[s.top().size()-1].y << ")" << endl;
  system("pause");
  --searchLevel;
  cout << "Go back.. " << endl;
  cout << "Search Level: " << searchLevel << endl;
  #endif
  chessboard[s.top()[s.top().size()-1].y][s.top()[s.top().size()-1].x] = false;
  return false;
}


/**
 * The program entry.
 *
 * @return an int indicating if the program run successfully.
 */
int main()
{
  int startIndex;
  Point startPoint;
  
  // Initialize the chessboard
  chessboard = new bool*[SIZE];
  for(int i=0;i<SIZE;++i) chessboard[i] = new bool[SIZE];
  
  // Loop do cases
  while(cin>>startIndex && startIndex>0)
  {
    #ifdef DEBUG
    cout << "=== NEW CASE: " << startIndex << " ===" << endl;
    #endif
    // Initialization
    for(int i=0;i<SIZE;++i) for(int j=0;j<SIZE;++j) chessboard[i][j] = false;
    while(!s.empty()) s.pop();
    
    // Initialize the start state
    startPoint.y = (startIndex - 1) / SIZE;
    startPoint.x = startIndex - startPoint.y * SIZE - 1;
    #ifdef DEBUG
    cout << "Start Point: (" << startPoint.x << ", " << startPoint.y << ")" << endl;
    cout << "Gone through: (" << startPoint.x << ", " << startPoint.y << ")" << endl;
    #endif
    chessboard[startPoint.y][startPoint.x] = true;
    #ifdef DEBUG
    vector<Point> _succ = successors(startPoint);
    cout << "Sucessors: ";
    for(int i=0;i<_succ.size();++i) cout << "(" << _succ[i].x << ", " << _succ[i].y << ") ";
    cout << endl;
    system("pause");
    #endif
    s.push(successors(startPoint));
    
    // Start the search
    if(search())
    {
      // Reverse the sequence
      stack<int> result;
      while(!s.empty())
      {
        result.push(s.top()[s.top().size()-1].y*SIZE + s.top()[s.top().size()-1].x + 1);
        s.pop();
      }
    
      // Display the result
      cout << startIndex;
      while(!result.empty())
      {
        cout << " " << result.top();
        result.pop();
      }
      cout << endl;
    }
    else cout << "ERROR" << endl;
  }
  
  // Release the resources
  for(int i=0;i<SIZE;++i) delete chessboard[i];
  delete chessboard;
  
  // Exit the program
  return 0;
}
